package jdtprototype;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.jar.Attributes.Name;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.epsilon.eol.exceptions.EolRuntimeException;
import org.eclipse.epsilon.eol.execute.Return;
import org.eclipse.epsilon.eol.execute.introspection.AbstractPropertyGetter;
import org.eclipse.epsilon.eol.parse.Eol_EolParserRules.newExpression_return;
import org.eclipse.epsilon.eol.parse.Eol_EolParserRules.returnStatement_return;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.core.dom.TypeDeclaration;

/**
 * This class retrieves the value of properties of JDT model element
 * 
 * @author Cheng Yun
 *
 */
public class JdtPropertyGetter extends AbstractPropertyGetter {
	JdtManipulator jdtManipulator;
	@Override
	public Object invoke(Object object, String property)
			throws EolRuntimeException {
		System.out.println("calling JdtPropertyGetter");
		
		if(object instanceof IJavaProject){//JavaProjact
			System.out.println("object instanceof IJavaProject ");
			
			if (property.equals("package")){//JavaProjact.package
				System.out.println("package was here");
				try {
					
					return JdtManipulator.getIPackageFragments((IJavaProject)object, true);
				} catch (CoreException e) {
					e.printStackTrace();
				}
			}
//			if (property.equals("class")){//JavaProjact.class
//				System.out.println("class was here");
//				try {
//					//returns a list of TypeDeclarations
//					return JdtManipulator.getTypeDeclaration((IJavaProject)object);
//				} catch (CoreException e) {
//					e.printStackTrace();
//				}
//			}
//			
			if(property.equals("name")){//JavaProjact.name

				return ((IJavaProject)object).getProject().getName();
			}
			
			if (property.equals("compilationUnit")){
				
				try {
					//returns a list of CompilationUnits
					return JdtManipulator.getCompilationUnits((IJavaProject)object);
				} catch (CoreException e) {
					e.printStackTrace();
				}
			}
			
			if (property.equals("class")){
				try {
					return JdtManipulator.getCompilationUnits((IJavaProject)object);
				} catch (CoreException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		
		if(object instanceof IPackageFragment){//package
			System.out.println("object instanceof IPackageFragment");
			if (property.equals("name")){//package.name
				System.out.println("return package.name");
				return ((IPackageFragment)object).getElementName();
			}
			if (property.equals("class")){//package.class
				System.out.println("return package.class");
				try {
					//return typeDeclarations;
					return JdtManipulator.getTypeDeclaration((IPackageFragment)object);
					
				} catch (CoreException e) {
					e.printStackTrace(); 
				}
				
			}
			if (property .equals("method")){
				try {
					return JdtManipulator.getMethodDeclaration((IPackageFragment)object);
				} catch (CoreException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}

		if(object instanceof TypeDeclaration){//class
			System.out.println("!!!!!object instanceof TypeDeclaration");
			
			if (property.equals("method")){//class.method
				return ((TypeDeclaration)object).getMethods();
			}
			
			if (property.equals("name")){//class.name
				System.out.println("class.name");
				return ((TypeDeclaration)object).getName().getFullyQualifiedName();
			}
		}
		
		if(object instanceof MethodDeclaration){//method
			System.out.println("object instanceof MethodDeclaration");
			if(property.equals("name")){
				
				return ((MethodDeclaration)object).getName().getFullyQualifiedName();
			}
			if(property.equals("modifier")){//method.modifier
				System.out.println("Modifier:"+((MethodDeclaration)object).getModifiers());
				return ((MethodDeclaration)object).getModifiers();
			}
		}
		
		return null;
	}

}
